/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../impl/head.h"
#include "notify_impl.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos_box
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    static notify_impl::ITEM_DATA xos_item_data;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    notify_impl::notify_impl()
    {
        init_data();
    }

    notify_impl::~notify_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int notify_impl::get_xos_item_data( ITEM_DATA *& item_ptr )
    {
        int ret = 0;
        xos_item_data.set_container( mgr::container() );
        item_ptr = &xos_item_data;
        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int notify_impl::set_threads( i_threads * pThreads, bool bUseSameThread )
    {
        int ret = 0;
        m_bUseSameThread = bUseSameThread;
        m_pThreads = pThreads;
        return ret;
    }

    int notify_impl::set_thread( i_callback * pThread )
    {
        int ret = 0;
        m_pThread = pThread;
        return ret;
    }

    int notify_impl::set_callback( xos::f_runnable pFun )
    {
        int ret = 0;
        m_pCallbackFun = pFun;
        return ret;
    }

    int notify_impl::set_msg_type( int nType )
    {
        int ret = 0;
        m_nMsgType = nType;
        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 通知方法
    int notify_impl::notify( i_msg *& pMsg, int nType, int nMsg )
    {
        int ret = 0;

        fill_msg( pMsg );
        pMsg->set_msg_type( nType );
        pMsg->set_msg( nMsg );
        ret = helper_notify( pMsg );

        return ret;
    }

    // 通知方法
    int notify_impl::notify( i_msg *& pMsg, int nMsg )
    {
        int ret = 0;

        fill_msg( pMsg );
        pMsg->set_msg( nMsg );
        ret = helper_notify( pMsg );

        return ret;
    }

    int notify_impl::notify( i_msg *& pMsg )
    {
        int ret = 0;

        fill_msg( pMsg );
        ret = helper_notify( pMsg );

        return ret;
    }

    int notify_impl::notify_type( i_msg *& pMsg, int nType )
    {
        int ret = 0;

        fill_msg( pMsg );
        pMsg->set_msg_type( nType );
        ret = helper_notify( pMsg );

        return ret;
    }

    int notify_impl::notify( int nMsg )
    {
        int ret = 0;

        i_msg * pMsg = mgr::get()->msg();
        ret = notify( pMsg, nMsg );
        xos_stl::release_interface( pMsg );

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    // 得到当前线程，两种情况可以得到线程：
    // 1、set_threads以bUseSameThread为true调用
    // 2、set_thread设置过线程了
    i_callback * notify_impl::get_cur_thread()
    {
        i_callback * pRet = m_pThread;

        if( !pRet && m_bUseSameThread && m_pThreads )
        {
            m_pThread = m_pThreads->get_thread_dispatch();
            pRet = m_pThread;
        }

        return pRet;
    }

    i_notify * notify_impl::clone()
    {
        i_notify * pN = 0;

        m_pEngine->create_notify( &pN );

        pN->set_threads( m_pThreads, m_bUseSameThread );
        pN->set_callback( m_pCallbackFun );
        pN->set_msg_type( m_nMsgType );
        pN->set_thread( m_pThread );

        return pN;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int notify_impl::helper_notify( i_msg *& pMsg )
    {
        int ret = 0;

        i_callback * pThread = get_cur_thread();

        if( !pThread )
        {
            if( !m_pThreads )
            {
                assert( false );
            }
            else
            {
                m_pThreads->notify( pMsg );
            }
        }
        else
        {
            pThread->notify( pMsg );
        }

        return ret;
    }

    int notify_impl::fill_msg( i_msg * pMsg ) const
    {
        int ret = 0;

        pMsg->set_runnable( 0, m_pCallbackFun );
        pMsg->set_msg_type( m_nMsgType );

        return ret;
    }

    int notify_impl::init_data()
    {
        int ret = 0;

        m_bUseSameThread = true;

        m_pThreads = 0;
        m_pThread = 0;
        m_pEngine = 0;

        m_pCallbackFun = 0;
        m_nMsgType = -1;

        return ret;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int notify_impl::set_engine( i_engine * pEngine )
    {
        int ret = 0;
        m_pEngine = pEngine;
        return ret;
    }

    int notify_impl::init()
    {
        int ret = 0;
        return ret;
    }

    int notify_impl::term()
    {
        int ret = 0;
        init_data();
        return ret;
    }

} // xos
